import os
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox, simpledialog
from ament_index_python import get_package_share_directory
import configparser
class ConfigManager:
    def __init__(self, package_name):
        self.package_share_dir = get_package_share_directory(package_name)
        self.config_dir = os.path.join(self.package_share_dir, "config")
        self.ini_file = os.path.join(self.config_dir, "logconfig.ini")
        os.makedirs(self.config_dir, exist_ok=True)
        self.config = configparser.ConfigParser()
        self._initialize_config()

    def _initialize_config(self):
        """初始化配置文件（如果不存在则创建默认配置）"""
        if not os.path.exists(self.ini_file):
            # 创建默认配置
            self.config['global'] = {
                'log_level': 'info',
                'async': 'true',
                'flush_level': 'warn',
                'max_file_size': '10MB',
                'max_files': '3'
            }
            self.save()
        else:
            self.config.read(self.ini_file)

        # 确保存在[global]段
        if not self.config.has_section('global'):
            self.config.add_section('global')
            self.save()
        
    def save(self):
        with open(self.ini_file, 'w') as configfile:
            self.config.write(configfile)

    def get_global_config(self):
        return dict(self.config['global'])

    def get_node_config(self):
        return {section: dict(self.config[section]) for section in self.config.sections() if section != 'global'}
    def update_node_config(self, node_name, max_file_size, max_files):
        if node_name in self.config:
            self.config[node_name]['max_file_size'] = max_file_size
            self.config[node_name]['max_files'] = str(max_files)
        else:
            messagebox.showerror("错误", "节点不存在")
    def add_node_config(self, node_name, max_file_size, max_files):
        if node_name not in self.config:
            self.config[node_name] = {'max_file_size': max_file_size, 'max_files': str(max_files)}
        else:
            messagebox.showerror("错误", "节点已存在")
    def delete_node_config(self, node_name):
        if node_name in self.config:
            self.config.remove_section(node_name)
        else:
            messagebox.showerror("错误", "节点不存在")
class App:
    def __init__(self, root, package_name):
        self.root = root
        try:
            self.config_manager = ConfigManager(package_name)
        except Exception as e:
            messagebox.showerror("初始化错误", f"无法加载配置: {str(e)}")
            root.destroy()
            return

        self.global_fields = [
            ('log_level', '日志级别'),
            ('async', '异步模式'),
            ('flush_level', '刷新级别'),
            ('max_file_size', '最大文件大小(MB)'),
            ('max_files', '最大文件数量')
        ]

        self.root.title("日志配置管理")
        self._create_tables()
        self._bind_events()
        self.display_configs()

    def _bind_events(self):
        """绑定右键菜单事件"""
        # 全局配置表格事件
        self.global_tree.bind("<Button-3>", self._on_global_right_click)
        
        # 节点配置表格事件
        self.node_tree.bind("<Button-3>", self._on_node_right_click)

    def _create_tables(self):
        """创建配置显示表格"""
        # 全局配置表格
        global_frame = tk.LabelFrame(self.root, text="全局配置")
        global_frame.pack(padx=10, pady=5, fill=tk.BOTH, expand=True)
        
        self.global_tree = ttk.Treeview(
            global_frame, 
            columns=('key', 'value'), 
            show='headings',
            height=1
        )
        self.global_tree.heading('key', text='配置项')
        self.global_tree.heading('value', text='值')
        self.global_tree.column('key', width=120, anchor='w')
        self.global_tree.column('value', width=250, anchor='w')
        self.global_tree.pack(fill=tk.X, padx=5, pady=5)

        global_scroll = ttk.Scrollbar(global_frame, orient=tk.VERTICAL, command=self.global_tree.yview)
        self.global_tree.configure(yscroll=global_scroll.set)
        self.global_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        global_scroll.pack(side=tk.RIGHT, fill=tk.Y)

        # 节点配置表格
        node_frame = tk.LabelFrame(self.root, text="节点配置")
        node_frame.pack(padx=10, pady=5, fill=tk.BOTH, expand=True)
        
        self.node_tree = ttk.Treeview(
            node_frame,
            columns=('node', 'max_size', 'max_files'),
            show='headings'
        )
        self.node_tree.heading('node', text='节点名称')
        self.node_tree.heading('max_size', text='最大文件大小(MB)')
        self.node_tree.heading('max_files', text='最大文件数量')
        self.node_tree.column('node', width=150, anchor='w')
        self.node_tree.column('max_size', width=120, anchor='w')
        self.node_tree.column('max_files', width=120, anchor='w')
        
        # 添加滚动条
        scrollbar = ttk.Scrollbar(node_frame, orient=tk.VERTICAL, command=self.node_tree.yview)
        self.node_tree.configure(yscroll=scrollbar.set)
        self.node_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

    def _on_global_right_click(self, event):
        """全局配置右键菜单"""
        item = self.global_tree.identify_row(event.y)
        if item:
            self.global_tree.selection_set(item)
            menu = tk.Menu(self.root, tearoff=0)
            menu.add_command(label="修改配置项", command=self._modify_global_item)
            menu.post(event.x_root, event.y_root)

    def _modify_global_item(self):
        """修改全局配置项"""
        selected = self.global_tree.selection()
        if not selected:
            return
        item = self.global_tree.item(selected[0])
        display_name  = item['values'][0]
        old_value = item['values'][1]

        english_key = None
        for key, chinese_name in self.global_fields:
            if chinese_name == display_name:
                english_key = key
                break

        if not english_key:
            messagebox.showerror("错误", "找不到对应的配置项！")
            return

        new_value = simpledialog.askstring("修改配置", f"请输入新的 {display_name} 值：", 
                                         initialvalue=old_value)
        if new_value is not None:
            try:
                # 更新配置并保存
                if (english_key == 'max_file_size'):
                    new_value = f"{new_value}MB"

                self.config_manager.config['global'][english_key] = new_value
                self.config_manager.save()
                
                # 添加调试信息
                print(f"DEBUG: 更新配置项 {english_key}={new_value} (显示名称: {display_name})")
                
                # 刷新显示
                self.display_configs()
                messagebox.showinfo("成功", "配置修改已保存")
            except Exception as e:
                messagebox.showerror("保存失败", f"保存配置时出错：{str(e)}")

    def _on_node_right_click(self, event):
        """节点配置右键菜单"""
        item = self.node_tree.identify_row(event.y)
        menu = tk.Menu(self.root, tearoff=0)
        
        if item:  # 点击在项目上
            self.node_tree.selection_set(item)
            menu.add_command(label="修改配置", command=self._modify_node_item)
            menu.add_command(label="删除配置", command=self._delete_node_item)
        else:     # 点击在空白处
            menu.add_command(label="新增配置", command=self._add_node_item)
            
        menu.post(event.x_root, event.y_root)

    def _add_node_item(self):
        """新增节点配置（整合到单个窗口）"""
        add_win = tk.Toplevel(self.root)
        add_win.title("新增节点配置")
        add_win.grab_set()
        
        # 输入控件容器
        input_frame = tk.Frame(add_win)
        input_frame.pack(padx=20, pady=10)

        # 节点名称
        tk.Label(input_frame, text="节点名称:").grid(row=0, column=0, sticky='e', padx=5, pady=5)
        node_entry = tk.Entry(input_frame, width=25)
        node_entry.grid(row=0, column=1, padx=5, pady=5)

        # 文件大小
        tk.Label(input_frame, text="最大文件大小(MB):").grid(row=1, column=0, sticky='e', padx=5, pady=5)
        size_entry = tk.Entry(input_frame, width=25, validate="key")
        size_entry['validatecommand'] = (size_entry.register(self._validate_number), '%P')
        size_entry.grid(row=1, column=1, padx=5, pady=5)
        tk.Label(input_frame, text="示例：10MB").grid(row=1, column=2, sticky='w', padx=5)

        # 文件数量
        tk.Label(input_frame, text="最大文件数量:").grid(row=2, column=0, sticky='e', padx=5, pady=5)
        files_entry = tk.Entry(input_frame, width=25)
        files_entry.grid(row=2, column=1, padx=5, pady=5)
        tk.Label(input_frame, text="示例：5").grid(row=2, column=2, sticky='w', padx=5)

        # 操作按钮
        def on_confirm():
            node_name = node_entry.get().strip()
            try:
                max_size = int(size_entry.get().strip())
                if not (1 <= max_size <= 100):
                    raise ValueError
            except ValueError:
                messagebox.showerror("输入错误", "文件大小必须是1-100之间的整数")
                return
            # max_size = size_entry.get().strip()
            max_files = files_entry.get().strip()

            if not all([node_name, max_size, max_files]):
                messagebox.showerror("输入错误", "所有字段必须填写！")
                return

            try:
                max_files = int(max_files)
                self.config_manager.add_node_config(node_name, max_size, max_files)
                self.config_manager.save()
                self.display_configs()
                add_win.destroy()
                messagebox.showinfo("成功", "节点配置已添加")
            except ValueError:
                messagebox.showerror("格式错误", "文件数量必须是整数")
            except Exception as e:
                messagebox.showerror("错误", str(e))

        btn_frame = tk.Frame(add_win)
        btn_frame.pack(pady=10)
        tk.Button(btn_frame, text="确认添加", command=on_confirm, width=10).pack(side=tk.LEFT, padx=10)
        tk.Button(btn_frame, text="取消", command=add_win.destroy, width=10).pack(side=tk.RIGHT, padx=10)

    def _modify_node_item(self):
        """修改节点配置弹窗"""
        selected = self.node_tree.selection()
        if not selected:
            return
            
        item = self.node_tree.item(selected[0])
        node_name = 'node.' + item['values'][0]
        old_size = item['values'][1]
        old_files = item['values'][2]

        # 创建子窗口
        edit_win = tk.Toplevel(self.root)
        edit_win.title("修改节点配置")
        edit_win.grab_set()

        # 输入框
        tk.Label(edit_win, text="节点名称：").grid(row=0, column=0, padx=5, pady=5)
        tk.Label(edit_win, text=node_name).grid(row=0, column=1, padx=5, pady=5)
        
        tk.Label(edit_win, text="最大文件大小(MB)：").grid(row=1, column=0, padx=5, pady=5)
        size_entry = tk.Entry(edit_win, validate="key")
        size_entry['validatecommand'] = (size_entry.register(self._validate_number), '%P')
        size_entry.insert(0, old_size)
        size_entry.grid(row=1, column=1, padx=5, pady=5)
        
        tk.Label(edit_win, text="最大文件数量：").grid(row=2, column=0, padx=5, pady=5)
        files_entry = tk.Entry(edit_win)
        files_entry.insert(0, old_files)
        files_entry.grid(row=2, column=1, padx=5, pady=5)

        # 确认按钮
        def confirm():
            try:
                new_size = int(size_entry.get())
                if not (1 <= new_size <= 100):
                    raise ValueError
            except ValueError:
                messagebox.showerror("输入错误", "文件大小必须是1-100之间的整数")
                return
            # new_size = size_entry.get()
            new_files = files_entry.get()
            if new_size and new_files:
                self.config_manager.update_node_config(
                    f"{node_name}", 
                    f"{new_size}MB", 
                    int(files_entry.get())
                )
                self.config_manager.save()
                self.display_configs()
                edit_win.destroy()
                
        tk.Button(edit_win, text="确认修改", command=confirm).grid(row=3, columnspan=2, pady=10)

    def _validate_number(self, input_str):
        """验证数字输入"""
        if input_str.isdigit() and 1 <= int(input_str) <= 100:
            return True
        elif input_str == "":
            return True
        return False

    def _delete_node_item(self):
        """删除节点配置"""
        selected = self.node_tree.selection()
        if not selected:
            return
            
        item = self.node_tree.item(selected[0])
        node_name = item['values'][0]
        if messagebox.askyesno("确认删除", f"确定要删除 {node_name} 的配置吗？"):
            self.config_manager.delete_node_config(f'node.{node_name}')
            self.config_manager.save()
            self.display_configs()

    def display_configs(self):
        """刷新表格数据"""
        # 清除旧数据
        self.global_tree.delete(*self.global_tree.get_children())
        self.node_tree.delete(*self.node_tree.get_children())
        
        # 加载全局配置
        global_config = self.config_manager.get_global_config()

        for key, display_name in self.global_fields:
            raw_value = global_config.get(key, 'N/A')
            if key == 'max_file_size':
                value = raw_value.replace('MB', '') if 'MB' in raw_value else raw_value
            else:
                value = raw_value
            self.global_tree.insert('', 'end', values=(display_name, value))
    

        # 加载节点配置
        node_configs = self.config_manager.get_node_config()
        for node, config in node_configs.items():
            node_name = node.replace("node.", "")
            self.node_tree.insert('', 'end', values=(
                node_name,
                config.get('max_file_size', 'N/A').replace("MB", ""),
                config.get('max_files', 'N/A')
            ))
    
if __name__ == "__main__":
    root = tk.Tk()
    root.geometry("800x600")  # 设置初始窗口大小
    app = App(root, package_name="rcl_logging_spdlog")
    root.mainloop()